import * as THREE from 'three'
import { useSceneStore } from '../../stores/scene'
import { useUserStore } from '../../stores/user'
import { CameraManager } from '../camera/CameraManager'
import { RendererManager } from '../renderer/RendererManager'

export class SceneManager {
  private scene: THREE.Scene
  private cameraManager: CameraManager
  private rendererManager: RendererManager
  private sceneStore = useSceneStore()
  private userStore = useUserStore()
  private daySkyboxTexture: THREE.CubeTexture | null = null; // Store the loaded day skybox texture

  constructor() {
    this.scene = new THREE.Scene()
    this.rendererManager = new RendererManager()
    this.cameraManager = new CameraManager(this.rendererManager.getRenderer().domElement)

    this.loadDaySkybox(); // Load skybox textures once

    // 初始化场景
    this.initScene()
    this.setupStateSync()
    this.initSkybox()
  }

  private loadDaySkybox(): void {
    const loader = new THREE.CubeTextureLoader();
    // 图片需要放在 public/skybox/ 目录下
    // Vite 会将 public 目录的内容直接服务于根路径，所以路径是 /skybox/...
    const texturePaths = [
      '/skybox/px.png', // 右 (Positive X)
      '/skybox/nx.png', // 左 (Negative X)
      '/skybox/py.png', // 上 (Positive Y)
      '/skybox/ny.png', // 下 (Negative Y)
      '/skybox/pz.png', // 前 (Positive Z)
      '/skybox/nz.png'  // 后 (Negative Z)
    ];

    this.daySkyboxTexture = loader.load(
      texturePaths,
      () => {
        console.log('Day skybox loaded successfully.');
        this.initSkybox(); // Re-apply skybox after successful load
      },
      undefined, // onProgress callback (optional)
      (error) => {
        console.error('Error loading day skybox: ', error);
        // Fallback to color if skybox fails to load
        this.daySkyboxTexture = null; // Ensure it's null so color fallback works
        this.initSkybox();
      }
    );
  }

  private initScene(): void {
    // 设置场景背景色
    this.scene.background = new THREE.Color(0x87ceeb)

    // 添加环境光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.3) // 稍微降低环境光强度，让定向光和阴影更突出
    this.scene.add(ambientLight)

    // 添加方向光
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8) // 增强定向光强度
    directionalLight.position.set(50, 80, 30) // 调整光源位置，使其从一个更合适的角度照射
    directionalLight.castShadow = true // 开启阴影投射
    directionalLight.shadow.mapSize.width = 2048 // 提高阴影贴图分辨率
    directionalLight.shadow.mapSize.height = 2048
    directionalLight.shadow.camera.near = 0.5
    directionalLight.shadow.camera.far = 500
    directionalLight.shadow.camera.left = -100
    directionalLight.shadow.camera.right = 100
    directionalLight.shadow.camera.top = 100
    directionalLight.shadow.camera.bottom = -100

    // 设置光源目标 (可选, 默认目标是原点 0,0,0)
    // directionalLight.target.position.set(0, 0, 0);
    // this.scene.add(directionalLight.target);

    this.scene.add(directionalLight)

    // 添加半球光，提供更柔和的环境光照
    const hemisphereLight = new THREE.HemisphereLight(0x87ceeb, 0x556B2F, 0.5);
    this.scene.add(hemisphereLight);

    // 添加地面
    const groundGeometry = new THREE.PlaneGeometry(500, 500, 50, 50) // 较大的平面，增加分段以便后续做地形起伏
    const groundMaterial = new THREE.MeshStandardMaterial({
      color: 0x556B2F, // 使用一个更自然的暗绿色
      roughness: 0.9, // 增加粗糙度，减少反光
      metalness: 0.1
    })
    const ground = new THREE.Mesh(groundGeometry, groundMaterial)
    ground.rotation.x = -Math.PI / 2 // 旋转平面使其水平
    ground.receiveShadow = true // 地面接收阴影
    this.scene.add(ground)

    // 添加雾效
    this.scene.fog = new THREE.Fog(0x87ceeb, 50, 300) // 颜色匹配白天天空，调整起始和终止距离

    // 设置阴影
    this.updateShadowSettings()
  }

  private initSkybox(): void {
    if (this.sceneStore.isNightMode) {
      this.scene.background = new THREE.Color(0x000033); // 夜晚天空颜色
      if (this.scene.fog instanceof THREE.Fog) {
        this.scene.fog.color.set(0x000033); // 夜晚雾颜色
      }
      const hemisphereLight = this.scene.children.find(child => child instanceof THREE.HemisphereLight) as THREE.HemisphereLight | undefined;
      if (hemisphereLight) {
        hemisphereLight.color.set(0x000033);
        hemisphereLight.groundColor.set(0x000000);
        hemisphereLight.intensity = 0.1;
      }
    } else {
      // 如果日间天空盒纹理已加载，则使用它
      if (this.daySkyboxTexture) {
        this.scene.background = this.daySkyboxTexture;
      } else {
        // 如果纹理加载失败或还未加载，则回退到纯色
        this.scene.background = new THREE.Color(0x87ceeb);
      }
      if (this.scene.fog instanceof THREE.Fog) {
        this.scene.fog.color.set(0x87ceeb);
      }
      const hemisphereLight = this.scene.children.find(child => child instanceof THREE.HemisphereLight) as THREE.HemisphereLight | undefined;
      if (hemisphereLight) {
        hemisphereLight.color.set(0x87ceeb);
        hemisphereLight.groundColor.set(0x556B2F);
        hemisphereLight.intensity = 0.5;
      }
    }
  }

  private setupStateSync(): void {
    // 监听场景状态变化
    this.sceneStore.$subscribe((mutation, state) => {
      // 直接使用 state 或 this.sceneStore 来获取最新的状态值
      this.updateLighting()
      this.initSkybox()
      this.updateShadowSettings()
      this.updatePostProcessing()
    })

    // 监听用户状态变化
    this.userStore.$subscribe((mutation, state) => {
      // 同样，直接使用 state 或 this.userStore
      this.updateUserSettings()
    })
  }

  private updateLighting(): void {
    const ambientLight = this.scene.children.find(child => child instanceof THREE.AmbientLight) as
      | THREE.AmbientLight
      | undefined
    const directionalLight = this.scene.children.find(
      child => child instanceof THREE.DirectionalLight
    ) as THREE.DirectionalLight | undefined
    const hemisphereLight = this.scene.children.find(
      child => child instanceof THREE.HemisphereLight
    ) as THREE.HemisphereLight | undefined

    if (!ambientLight || !directionalLight || !hemisphereLight) return // Guard against missing lights

    if (this.sceneStore.isNightMode) {
      ambientLight.intensity = 0.1
      directionalLight.intensity = 0.2
      directionalLight.position.set(20, 40, 30)
      // Hemisphere light colors are updated in initSkybox/updateSkyBackgroundAndFog
    } else {
      ambientLight.intensity = 0.3
      directionalLight.intensity = 0.8
      directionalLight.position.set(50, 80, 30)
      // Hemisphere light colors are updated in initSkybox/updateSkyBackgroundAndFog
    }
  }

  private updateShadowSettings(): void {
    const directionalLight = this.scene.children.find(
      child => child instanceof THREE.DirectionalLight
    ) as THREE.DirectionalLight

    if (directionalLight) {
      directionalLight.castShadow = this.sceneStore.isShadowsEnabled
    }
    this.scene.traverse(child => {
      if (child instanceof THREE.Mesh) {
        child.castShadow = this.sceneStore.isShadowsEnabled;
        // Meshes like ground already have receiveShadow = true set up.
        // If other meshes need to receive shadows, set it during their creation.
      }
    });
  }

  private updatePostProcessing(): void {
    this.rendererManager.setBloomEnabled(this.sceneStore.isBloomEnabled)
  }

  private updateUserSettings(): void {
    // 更新用户相关设置
    // 例如：移动速度、音量等
  }

  public getScene(): THREE.Scene {
    return this.scene
  }

  public getCameraManager(): CameraManager {
    return this.cameraManager
  }

  public getRendererManager(): RendererManager {
    return this.rendererManager
  }

  public update(): void {
    // 更新场景中的对象
    this.cameraManager.update()
    this.rendererManager.render(this.scene, this.cameraManager.getCamera())
  }

  public dispose(): void {
    this.rendererManager.dispose()
    // Add other disposal logic for SceneManager if needed
  }
}
